/********************************************************************************************/
/* Fullhan Technology (Shanghai) Co., Ltd.                                                  */
/* Fullhan Proprietary and Confidential                                                     */
/* Copyright (c) 2014 Fullhan Technology Group Limited and its affiliated companies         */
/********************************************************************************************/
#ifndef __FH_UNF_CESA_H__
#define __FH_UNF_CESA_H__

#if defined(CONFIG_CRYPTO_DEV_FH_CESA) || defined(CONFIG_CRYPTO_DEV_FH_CESA_TEE)
#include <linux/fs.h>
#else
#include <stdint.h>
#include <stdbool.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif

#define CRYPTO_CPU_SET_KEY                    (1<<0)
#define CRYPTO_EX_MEM_SET_KEY                 (1<<1)
#define CRYPTO_EX_MEM_INDEP_POWER             (1<<2)
#define CRYPTO_EX_MEM_SWITCH_KEY              (1<<8)
#define CRYPTO_EX_MEM_4_ENTRY_1_KEY           (1<<9)

//==========================ADES================================
typedef enum  _FH_CESA_ADES_OPER_MODE_E {
	FH_CESA_ADES_OPER_MODE_ENCRYPT,
	FH_CESA_ADES_OPER_MODE_DECRYPT,
} FH_CESA_ADES_OPER_MODE_E;

typedef enum  _FH_CESA_ADES_ALGO_MODE_E {
	FH_CESA_ADES_ALGO_MODE_AES128,
	FH_CESA_ADES_ALGO_MODE_AES192,
	FH_CESA_ADES_ALGO_MODE_AES256,
	FH_CESA_ADES_ALGO_MODE_DES,
	FH_CESA_ADES_ALGO_MODE_TDES,
} FH_CESA_ADES_ALGO_MODE_E;

typedef enum  _FH_CESA_ADES_WORK_MODE_E {
	FH_CESA_ADES_WORK_MODE_ECB,
	FH_CESA_ADES_WORK_MODE_CBC,
	FH_CESA_AES_WORK_MODE_CTR,
	FH_CESA_ADES_WORK_MODE_CFB8,
	FH_CESA_ADES_WORK_MODE_OFB,
} FH_CESA_ADES_WORK_MODE_E;


typedef enum _FH_CESA_ADES_KEY_SRC_E {
	FH_CESA_ADES_KEY_SRC_USER = CRYPTO_CPU_SET_KEY,
	FH_CESA_ADES_KEY_SRC_EFUSE = CRYPTO_EX_MEM_SET_KEY,
	FH_CESA_ADES_KEY_SRC_BUTT
} FH_CESA_ADES_KEY_SRC_E;

typedef struct _FH_CESA_ADES_CTRL_S {
	FH_CESA_ADES_OPER_MODE_E oper_mode;
	FH_CESA_ADES_ALGO_MODE_E algo_mode;
	FH_CESA_ADES_WORK_MODE_E work_mode;
	uint8_t key[32];
	uint8_t iv[16];
	FH_CESA_ADES_KEY_SRC_E enKeySrc;
	bool self_key_gen;
	uint8_t self_key_text[32];
} FH_CESA_ADES_CTRL_S;

typedef struct _FH_CESA_ADES_EFUSE_PARA_S {
	uint32_t mode;
	uint32_t map_size;
	struct {
		uint32_t crypto_key_no;
		uint32_t ex_mem_entry;
	} map[8];
} FH_CESA_ADES_EFUSE_PARA_S;

typedef enum  _FH_CESA_ADES_ADDR_ATTR_E {
	FH_CESA_ADES_ADDR_ATTR_PHY,
	FH_CESA_ADES_ADDR_ATTR_VIR,
} FH_CESA_ADES_ADDR_ATTR_E;

//==========================SHA================================
typedef enum  _FH_CESA_SHA_ALGO_MODE_E
{
	FH_CESA_HASH_ALGO_MODE_SHA1,
	FH_CESA_HASH_ALGO_MODE_SHA224,
	FH_CESA_HASH_ALGO_MODE_SHA256,
	FH_CESA_HASH_ALGO_MODE_HMAC_SHA256,
	FH_CESA_HASH_ALGO_MODE_MAX,
}FH_CESA_SHA_ALGO_MODE_E;

typedef struct _FH_CESA_SHA_PARA_S
{  
	uint8_t *hmac_key;
	uint32_t key_size;
	uint8_t o_key_pad[64];
	uint8_t i_key_pad[64];

	FH_CESA_SHA_ALGO_MODE_E algo_mode;
} FH_CESA_SHA_PARA_S;

typedef struct  _FH_CESA_SHA_CTRL_S
{
	FH_CESA_SHA_PARA_S sha_para;
}FH_CESA_SHA_CTRL_S;

//==========================RSA================================
typedef struct _FH_CESA_RSA_PARA_S
{
	uint8_t *p_m;			//modulus
	uint8_t *p_e;			//exponent
	uint32_t mod_length;
	uint32_t exp_length;
} FH_CESA_RSA_PARA_S;

typedef struct _FH_CESA_RSA_CTRL_S
{
	FH_CESA_RSA_PARA_S rsa_para;
} FH_CESA_RSA_CTRL_S;



int32_t FH_UNF_CESA_Open(void);
int32_t FH_UNF_CESA_Close(void);
int32_t FH_UNF_CESA_ADES_Create(uint32_t *p_session);
int32_t FH_UNF_CESA_ADES_Destroy(uint32_t session);
int32_t FH_UNF_CESA_ADES_Config(uint32_t session, FH_CESA_ADES_CTRL_S *p_ctrl);
int32_t FH_UNF_CESA_ADES_Process(uint32_t session, uint32_t p_src_addr, uint32_t p_dst_addr, uint32_t length);
int32_t FH_UNF_CESA_ADES_Encrypt(uint32_t session, uint32_t p_src_addr, uint32_t p_dst_addr, uint32_t length);
int32_t FH_UNF_CESA_ADES_Decrypt(uint32_t session, uint32_t p_src_addr, uint32_t p_dst_addr, uint32_t length);
int32_t FH_UNF_CESA_ADES_Get_Info(uint32_t session, FH_CESA_ADES_CTRL_S *ctrl);
int32_t FH_UNF_CESA_ADES_Efuse_Key(uint32_t session, uint32_t *u32MapBuf, uint32_t u32MapBufSize);
int32_t FH_UNF_CESA_ADES_Addr_Attr(uint32_t session,
				FH_CESA_ADES_ADDR_ATTR_E src_addr_attr,
				FH_CESA_ADES_ADDR_ATTR_E dst_addr_attr);
int32_t FH_UNF_CESA_SHA_Create(uint32_t *p_session);
int32_t FH_UNF_CESA_SHA_Destroy(uint32_t session);
int32_t FH_UNF_CESA_SHA_Init(uint32_t session, FH_CESA_SHA_CTRL_S *p_ctrl);
int32_t FH_UNF_CESA_SHA_Update(uint32_t session, uint8_t *p_msg, uint32_t length);
int32_t FH_UNF_CESA_SHA_Final(uint32_t session, uint8_t *p_dgst);
int32_t FH_UNF_CESA_SHA_Update_Start(uint32_t session, uint8_t *p_msg, uint32_t length);
int32_t FH_UNF_CESA_SHA_Update_Polling(uint32_t session, uint32_t timeout);
int32_t FH_UNF_CESA_SHA_Update_Stop(uint32_t session);
int32_t FH_UNF_CESA_HMACSHA_Init(uint32_t session, FH_CESA_SHA_CTRL_S *p_ctrl);
int32_t FH_UNF_CESA_HMACSHA_Update(uint32_t session, FH_CESA_SHA_CTRL_S *p_ctrl, uint8_t *p_msg, uint32_t length);
int32_t FH_UNF_CESA_HMACSHA_Final(uint32_t session, FH_CESA_SHA_CTRL_S *p_ctrl, uint8_t *p_dgst);
int32_t FH_UNF_CESA_RSA_Create(uint32_t *p_session);
int32_t FH_UNF_CESA_RSA_Destroy(uint32_t session);
int32_t FH_UNF_CESA_RSA_Process(uint32_t session, FH_CESA_RSA_CTRL_S *p_ctrl, uint8_t *p_src_addr, uint8_t *p_dst_addr, uint32_t src_length);
int32_t FH_UNF_CESA_Gen_Random_Bytes(uint32_t NumOfBytes, uint8_t*  pRandomBytes);
int32_t FH_UNF_CESA_RSA_padding_add_OAEP(uint8_t *to, int32_t tlen, uint8_t *from, int32_t flen, uint32_t hashtype);
int32_t FH_UNF_CESA_RSA_padding_check_OAEP(uint8_t *to, int32_t *tlen, uint8_t *from, int32_t flen, int32_t num, uint32_t hashtype);
#ifdef __cplusplus
}
#endif

#endif //__FH_UNF_CESA_H__


#ifndef __CESA_RESULT_H__
#define __CESA_RESULT_H__
/*!
  Result Code
  */
#define CESA_SUCCESS	0

#define CESA_INVALID_VALUE						-1
#define CESA_INIT_FAILED						-4
#define CESA_ALREADY_OPENED						-5

#define CESA_ADES_HDLR_GET_FAILED				-100
#define CESA_ADES_HDLR_SET_INVALID				-101
#define CESA_ADES_OPER_MODE_ERROR				-102
#define CESA_ADES_ALGO_MODE_ERROR				-103
#define CESA_ADES_WORK_MODE_ERROR				-104
#define CESA_ADES_WORK_ALGO_MODE_CONFLICT		-105
#define CESA_ADES_DATA_LENGTH_ERROR				-106
#define CESA_ADES_DMA_ADDR_ERROR				-107
#define CESA_ADES_DMA_DONE_TIMEOUT				-108
#define CESA_ADES_KEY_SRC_ERROR					-109
#define CESA_ADES_CONFIG_TEE_ERROR				-110
#define CESA_ADES_PROCESS_TEE_ERROR				-111

#define FH_SUCCESS       0
#define FH_FAILURE       (-1)

#define FH_ASSERT(_expr, _format, _args...) do { \
	if (!(_expr)) { pr_err("%s:%s:%d: " _format "\n", \
						in_irq() ? "IRQ" : "", \
				      __FILE__, __LINE__, ## _args); \
						BUG_ON(1); } \
	} while (0)

#endif	/*__CESA_RESULT_H__*/

